#pragma once

#include "common.h"
#include "thread_cache.h"
#include "page_cache.h"
#include "Memory_pools.h"

static void *ConcurrentAlloc(size_t size)
{
    // 大于128页的直接向堆申请
    if (size > MAX_BYTES)
    {
        size_t alignSize = SizeClass::RoundUp(size);
        size_t kpage = alignSize >> PAGE_SHIFT;

        Span *span = PageCache::GetInstance()->NewSpan(size);
        PageCache::GetInstance()->_pageMtx.lock();
        span->objSzie = size;
        PageCache::GetInstance()->_pageMtx.unlock();

        void *ptr = (void *)(span->_page_id << PAGE_SHIFT);
        return ptr;
    }
    else
    {
        // 通过TLS每个线程无锁获取各自的ThreadCache对象
        if (pTLSThreadCache == nullptr)
        {
            // pTLSThreadCache = new ThreadCache;
            static ObjectPool<ThreadCache> tcPoll;
            pTLSThreadCache = tcPoll.New();
        }

        // LOG(DEBUG, "this_thread_pid: %d\n", std::this_thread::get_id());
        // LOG(DEBUG, "进入thread_cache, 申请内存大小: %d\n", size);
        return pTLSThreadCache->Allocate(size);
    }
}

static void ConcurrentFree(void *ptr)
{
    Span *span = PageCache::GetInstance()->MapObjictToSpan(ptr);
    size_t size = span->objSzie;
    // 大于128页的直接向堆申请
    if (size > MAX_BYTES)
    {
        PageCache::GetInstance()->_pageMtx.lock();
        PageCache::GetInstance()->ReleaseSpanTOPageCache(span);
        PageCache::GetInstance()->_pageMtx.unlock();
    }
    else
    {
        assert(pTLSThreadCache);

        pTLSThreadCache->Deallocate(ptr, size);
    }
}